home *** CD-ROM | disk | FTP | other *** search
/ Mac Easy 2010 May / Mac Life Ubuntu.iso / casper / filesystem.squashfs / usr / src / linux-headers-2.6.28-15 / include / linux / math64.h < prev    next >
Encoding:
C/C++ Source or Header  |  2008-12-24  |  2.2 KB  |  106 lines

  1. #ifndef _LINUX_MATH64_H
  2. #define _LINUX_MATH64_H
  3.  
  4. #include <linux/types.h>
  5. #include <asm/div64.h>
  6.  
  7. #if BITS_PER_LONG == 64
  8.  
  9. /**
  10.  * div_u64_rem - unsigned 64bit divide with 32bit divisor with remainder
  11.  *
  12.  * This is commonly provided by 32bit archs to provide an optimized 64bit
  13.  * divide.
  14.  */
  15. static inline u64 div_u64_rem(u64 dividend, u32 divisor, u32 *remainder)
  16. {
  17.     *remainder = dividend % divisor;
  18.     return dividend / divisor;
  19. }
  20.  
  21. /**
  22.  * div_s64_rem - signed 64bit divide with 32bit divisor with remainder
  23.  */
  24. static inline s64 div_s64_rem(s64 dividend, s32 divisor, s32 *remainder)
  25. {
  26.     *remainder = dividend % divisor;
  27.     return dividend / divisor;
  28. }
  29.  
  30. /**
  31.  * div64_u64 - unsigned 64bit divide with 64bit divisor
  32.  */
  33. static inline u64 div64_u64(u64 dividend, u64 divisor)
  34. {
  35.     return dividend / divisor;
  36. }
  37.  
  38. #elif BITS_PER_LONG == 32
  39.  
  40. #ifndef div_u64_rem
  41. static inline u64 div_u64_rem(u64 dividend, u32 divisor, u32 *remainder)
  42. {
  43.     *remainder = do_div(dividend, divisor);
  44.     return dividend;
  45. }
  46. #endif
  47.  
  48. #ifndef div_s64_rem
  49. extern s64 div_s64_rem(s64 dividend, s32 divisor, s32 *remainder);
  50. #endif
  51.  
  52. #ifndef div64_u64
  53. extern u64 div64_u64(u64 dividend, u64 divisor);
  54. #endif
  55.  
  56. #endif /* BITS_PER_LONG */
  57.  
  58. /**
  59.  * div_u64 - unsigned 64bit divide with 32bit divisor
  60.  *
  61.  * This is the most common 64bit divide and should be used if possible,
  62.  * as many 32bit archs can optimize this variant better than a full 64bit
  63.  * divide.
  64.  */
  65. #ifndef div_u64
  66. static inline u64 div_u64(u64 dividend, u32 divisor)
  67. {
  68.     u32 remainder;
  69.     return div_u64_rem(dividend, divisor, &remainder);
  70. }
  71. #endif
  72.  
  73. /**
  74.  * div_s64 - signed 64bit divide with 32bit divisor
  75.  */
  76. #ifndef div_s64
  77. static inline s64 div_s64(s64 dividend, s32 divisor)
  78. {
  79.     s32 remainder;
  80.     return div_s64_rem(dividend, divisor, &remainder);
  81. }
  82. #endif
  83.  
  84. u32 iter_div_u64_rem(u64 dividend, u32 divisor, u64 *remainder);
  85.  
  86. static __always_inline u32
  87. __iter_div_u64_rem(u64 dividend, u32 divisor, u64 *remainder)
  88. {
  89.     u32 ret = 0;
  90.  
  91.     while (dividend >= divisor) {
  92.         /* The following asm() prevents the compiler from
  93.            optimising this loop into a modulo operation.  */
  94.         asm("" : "+rm"(dividend));
  95.  
  96.         dividend -= divisor;
  97.         ret++;
  98.     }
  99.  
  100.     *remainder = dividend;
  101.  
  102.     return ret;
  103. }
  104.  
  105. #endif /* _LINUX_MATH64_H */
  106.